//obsolete comments

// Test of PWM (phase correct) output on pins 11 of the ArduinoMEGA board.
// We want a PWM frequency >> 4kHz, and a resolution of at least 12 bits (4096 levels), and more if possible. 

/* ==========================================================================================================================
 NOTES: 
 
 The 16-bit timer/counter TCNT1 controls the output compare pins OC1A, OC1B and OC1C 
 (these are respectively pins PB5, PB6 and PB7 on the ATMEGA1280, or pins 11, 12 and 13 of the ArduinoMEGA board)
 
 * The CLOCK SOURCE is selected by the Clock Select logic which is controlled by the Clock Select (CSn2:0) bits located in 
 the Timer/Counter control Register B (TCCRnB). The Timer/Counter can be clocked directly by the system clock by setting the CSn2:0 = 1.
 
 * PRESCALER: Timer/Counter 0, 1, 3, 4, and 5 share the same prescaler module, but the Timer/Counters (Tn) can
 have different prescaler settings (fig. 18-2 on page 171 of ATmega2180 manual).
 One of four taps from the prescaler can be used as a clock source Tn (selected by CSn2:0 bits though a multiplexor). 
 The prescaled clock Tn has a frequency of either fclk_io/1, fclk_io/8, fclk_io/64, fclk_io/256, or fclk_io/1024, where fclk_io is the 
 "input/output" clock derived from the internal clock (from the prescaler perhaps, using the SYSTEM prescaler setting on register CLKPR. But
 note that in this case, even the sytem clock will be affected!). Note that CSn2:0={000} means NO CLOCK (freeze counter). 
 
 The counting sequence (bottom-top|bottom-top|... or bottom-top-bottom-top...)is determined by the setting of the Waveform Generation mode bits
 (WGMn3:0) located in the Timer/Counter Control Registers A and B (TCCRnA and TCCRnB).
 
 The ICRn Register (input capute register) can only be written when using a Waveform Generation mode that utilizes
 the ICRn Register for defining the counters TOP value. In these cases the Waveform Generation
 mode (WGMn3:0) bits must be set before the TOP value can be written to the ICRn Register.
 
 The 16-bit comparator continuously compares TCNTn with the Output Compare Register
 (OCRnx). If TCNT equals OCRnx the comparator signals a match. 
 
 * The COMPARE OUPUT MODE is defined by bits COMnx1:0. These bits define how the OCnx pin change when this match takes place: 
 For non-PWM modes the COMnx1:0 bits control whether the output should be set, cleared or toggle at a compare
 match. In PWM mode, the COMnx1:0 bits control whether the PWM output generated should be inverted or not (inverted or non-inverted PWM). 
 
 * The WAVEFORM GENERATION MODE is defined by bits WGMn3:0 (spread in registers TCCRnA and TCCRnB). 
 
 * The MODE OF OPERATION, i.e., the behavior of the Timer/Counter and the Output Compare pins, is
 defined by the combination of the Waveform Generation mode (WGMn3:0) and Compare Output
 mode (COMnx1:0) bits. The Compare Output mode bits do not affect the counting sequence,
 while the Waveform Generation mode bits do.
 
 The Waveform Generator uses the match signal to generate an output according to operating mode set by the Waveform Generation mode
 (WGMn3:0) bits and Compare Output mode (COMnx1:0) bits. The TOP and BOTTOM signals are used by the Waveform Generator for handling 
 the special cases of the extreme values in some modes of operation
 
 A special feature of Output Compare unit A allows it to define the Timer/Counter TOP value (i.e.,
 counter resolution). In addition to the counter resolution, the TOP value defines the period time
 for waveforms generated by the Waveform Generator.
 
 EXAMPLES for counter TCNT1 and output compare pin OC1A, using internal clock without prescaling:
 // MODE OF OPERATION: Phase and Frequency Correct PWM Mode & COMPARE OUPUT MODE as non-inverted output on OC1A:
 //     - Phase and Frequency Correct PWM Mode set when WGM1[3:0] = 8 or 9. 
 //     - For fixed PWM period, TOP can be defined as ICR1: this is achieved by doing: WGM1[3:0] = 8 (B1000)
 //       (this means setting TCCR1A[1:0]=WGM1[1:0]=B00 and TCCR1B[4:3]=WGM1[3:2]=B10)  
 //     - When in Phase and Freq. correct, then non inverted PWM output when COM1A[1:0]=B11 (Set OC1A on compare match when up-counting, and clear it when downcounting)
 //     - Use internal clock without prescaling (N=1) by setting: CS1[2:0] = B001 (TCCR1B[2:0]=B001)
 
 * In Phase and Freq correct PWM mode, the PWM cycle is given by T0 = 2*TOP/(fclk_io/N), i.e. F0= fclk_io/(2*TOP*N)
 * The resolution (in bits) is given by log(TOP)/log(2) (equal to log(ICR1)/log(2) when setting TOP=ICR1).
 * If I want F0>>4kHz (to be able to filter and have a "continuous" signal with a bandwith > 4kHz), and TOP (resolution) as large as possible;
 this means N=1, leading to TOP<<2000... this is not enough!!  (I need a resolution of at least 11 bits or better 12 bits!)
 
 ** ATTENTION:  the Arduino runtime runs the millis() function from the Timer 0 interrupt
 
 ** NOTE: in wiring.c, the init values for the control registers TCCR1A and TCCR1B for the ATmega1280 come from this piece of code: 
 ...
 	// timers 1 and 2 are used for phase-correct hardware pwm
 	// this is better for motors as it ensures an even waveform
 	// note, however, that fast pwm mode can achieve a frequency of up
 	// 8 MHz (with a 16 MHz clock) at 50% duty cycle
 
 	// set timer 1 prescale factor to 64
 	sbi(TCCR1B, CS11); sbi(TCCR1B, CS10);
 	// put timer 1 in 8-bit phase correct pwm mode
 	sbi(TCCR1A, WGM10);
 ...
 
 =========================================================================================================================== */
 
 
int testPin_OC1A=11; // this is, output compare pin OC1A //connected to CK2 = lockIn clock
int testPin_OC1B=12; // this is, output compare pin OC1B //connected to CK1 = laser clock
int testPin_OC1C=13;

void setupPWM(){
  
  pinMode (testPin_OC1A, OUTPUT);
  pinMode (testPin_OC1B, OUTPUT);
  pinMode (testPin_OC1C, OUTPUT);

  //(1) Phase and Frequency Correct PWM Mode for Timer/Counter 1, with TOP=ICR1: WGM1[3:0] = 8 
  // TCCR1A bits:	        COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
  // set bits:	                                                          0     0
  // TCCR1B bits:	        ICNC1  ICES1  -      WGM13  WGM12  CS12   CS11  CS10 
  // set bits:                                       1      0

  // (1.b) Or Fast PWM with TOP=ICR1: WGM1[3:0] = B1110 (=14) 
  // TCCR1A bits:	        COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
  // set bits:	                                                          1     0
  // TCCR1B bits:	        ICNC1  ICES1  -      WGM13  WGM12  CS12   CS11  CS10 
  // set bits:                                       1      1

  // (2) When in Phase and Freq. correct or on fast PWM, non inverted PWM output on OC1A when COM1A[1:0]=B11, and on OC1B when COM1B[1:0]=B11
  // TCCR1A bits:	        COM1A1 COM1A0 COM1B1 COM1B0 COM1C1 COM1C0 WGM11 WGM10
  // set bits:	                1      1      1      1       1    1       X     X

  // (3)  Use internal clock without prescaling (N=1) by setting: CS1[2:0] = B001 (TCCR1B[2:0]=B001):
  // TCCR1B bits:	        ICNC1  ICES1  -      WGM13  WGM12  CS12   CS11  CS10 
  // set bits:                  X      X      X      X      X      0      0     1

  // Conclusion: overriding the default values of the control registers TCCR1A and TCCR1B (this will affect pins 11, 12 and 13), we would do: 
  // For phase and frequency correct PWM:
  //TCCR1A = B11111100;
  //TCCR1B = B00010001;
  // And for fast PWM:
  TCCR1A = B11111110;
  TCCR1B = B00011001;
  

  // TOP VALUE for the TCNT1 counter is ICR1 (and gives the resolution):
  ICR1 = 64 ; // 10 bit resolution (perhaps not enough for smoothly positioning and generating the laser saccade, but let's try)
  // This means:
  // (a) for phase and frequency correct: Fpwm= 16e6/(2*1024*1) = 7.8125 kHz, or Tpwm= 1/Fpwm = 128us
  // (b) for fast PWM: double of this (15.625kHz, period of 64 us).

  // The PWM duty cycle on OC1A pin (pin 11) is given by the value of the register OCR1A:
  OCR1A = 1; // vary this value between 0 and ICR1=1024 for 10-bit precision
  OCR1B = 36;// best value, calibrate by hand.
  
  
}
